using B.S.NewMedical.Api.Write.Application.Command.Doctor;
using B.S.NewMedical.Domain.Appointment;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace B.S.NewMedical.Api.Write.Application.Handler.Doctor
{
    /// <summary>
    /// 开始接诊处理器
    /// </summary>
    public class StartVisitHandler : IRequestHandler<StartVisitCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<Registration> _registrationRepository;
        private readonly IBaseRepository<Visit> _visitRepository;
        private readonly MyDbcontext _dbContext;
        private readonly ILogger<StartVisitHandler> _logger;

        public StartVisitHandler(
            IBaseRepository<Registration> registrationRepository,
            IBaseRepository<Visit> visitRepository,
            MyDbcontext dbContext,
            ILogger<StartVisitHandler> logger)
        {
            _registrationRepository = registrationRepository;
            _visitRepository = visitRepository;
            _dbContext = dbContext;
            _logger = logger;
        }

        public async Task<ApiResult<int>> Handle(StartVisitCommand request, CancellationToken cancellationToken)
        {
            using var transaction = await _dbContext.Database.BeginTransactionAsync(cancellationToken);
            try
            {
                _logger.LogInformation("开始处理接诊，挂号ID: {RegistrationId}", request.RegistrationId);

                // 参数验证
                if (request.RegistrationId <= 0)
                    return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "挂号ID不能为空" };

                if (string.IsNullOrWhiteSpace(request.ChiefComplaint))
                    return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "主诉不能为空" };

                if (string.IsNullOrWhiteSpace(request.DiagnosisText))
                    return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "诊断描述不能为空" };

                // 检查挂号是否存在且状态正确
                var registration = await _registrationRepository.GetAll()
                    .FirstOrDefaultAsync(r => r.Id == request.RegistrationId && !r.IsDeleted, cancellationToken);

                if (registration == null)
                    return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "挂号记录不存在" };

                if (registration.Status != "待就诊")
                    return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "挂号状态不正确，无法接诊" };

                // 检查是否已经接诊过
                var existingVisit = await _visitRepository.GetAll()
                    .FirstOrDefaultAsync(v => v.Registration_id == request.RegistrationId && !v.IsDeleted, cancellationToken);

                if (existingVisit != null)
                    return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "该患者已接诊过" };

                // 创建就诊记录
                var visit = new Visit
                {
                    Registration_id = registration.Id,
                    Patient_id = registration.Patient_id,
                    Doctor_id = registration.Doctor_id,
                    Visit_time = DateTime.Now,
                    Chief_complaint = request.ChiefComplaint,
                    Diagnosis_text = request.DiagnosisText,
                    Treatment_plan = request.TreatmentPlan,
                    Remark = request.Remark,
                    IsDeleted = false
                };

                await _visitRepository.CreateAsync(visit);

                // 更新挂号状态
                registration.Status = "已就诊";
                await _registrationRepository.UpdateAsync(registration);

                await _dbContext.SaveChangesAsync(cancellationToken);
                await transaction.CommitAsync(cancellationToken);

                _logger.LogInformation("接诊成功，就诊ID: {VisitId}，挂号ID: {RegistrationId}", visit.Id, request.RegistrationId);

                return new ApiResult<int>
                {
                    Code = ApiEnum.Success,
                    Msg = "接诊成功",
                    Data = visit.Id
                };
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync(cancellationToken);
                _logger.LogError(ex, "接诊时发生错误，挂号ID: {RegistrationId}", request.RegistrationId);
                return new ApiResult<int>
                {
                    Code = ApiEnum.Fail,
                    Msg = "接诊失败"
                };
            }
        }
    }
} 